import { CSS2DObject, THREE } from '@amcax/web-render';

export type css2dLabelAttrs = {
  position: THREE.Vector3; // 位置
  text: string | number | HTMLDivElement; // 文本
  id?: string | number; // 对应的id
  name: string; // 类名
};

export class css2dLabel {
  labelObject: CSS2DObject;
  width: number;
  heigth: number;

  constructor(attrs?: css2dLabelAttrs) {
    this.initialize(attrs);
  }

  getType() {
    return 'css2dLabel';
  }

  initialize(attrs?: css2dLabelAttrs) {
    const id = attrs.id;
    const name = attrs.name;
    // let pos = attrs.position.clone()
    const pos = attrs.position;
    const css2dLabelDiv = document.createElement('div');
    css2dLabelDiv.className = name;
    if (id) {
      css2dLabelDiv.id = `${name}_${id}`;
    }
    if (attrs.text instanceof HTMLDivElement) {
      css2dLabelDiv.appendChild(attrs.text);
    } else {
      css2dLabelDiv.textContent = attrs.text ? '' + attrs.text : '100.00';
    }
    this.labelObject = new CSS2DObject(css2dLabelDiv);
    this.labelObject.position.set(pos.x, pos.y, pos.z);
    this.labelObject.name = 'css2dLabel';
  }

  update({
    text,
    pos,
  }: {
    text: number | string | HTMLDivElement;
    pos?: THREE.Vector3;
  }) {
    if (text instanceof HTMLDivElement) {
      this.labelObject.element.appendChild(text);
    } else {
      this.labelObject.element.textContent = '' + text;
    }
    if (pos) {
      this.labelObject.position.set(pos.x, pos.y, pos.z);
    }
  }
  async getWidthAndHeight() {
    return await new Promise<{ width: number; height: number }>((resolve) => {
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          // 在下一帧渲染周期后获取尺寸
          resolve({
            width: this.labelObject.element.clientHeight,
            height: this.labelObject.element.clientHeight,
          });
        });
      });
    });
  }

  updatePosition(pos: THREE.Vector3) {
    this.labelObject.position.set(pos.x, pos.y, pos.z);
  }

  getWidth() {
    return this.labelObject?.element.clientHeight || 0;
  }

  getHeight() {
    return this.labelObject?.element.clientHeight || 0;
  }

  /**
   * @description 添加到场景中去
   * @param { Object3D } scene
   **/
  addTo(scene: THREE.Object3D) {
    scene.add(this.labelObject);
  }

  hide() {
    this.labelObject.visible = false;
  }

  show() {
    this.labelObject.visible = true;
  }
  destroy() {
    this.labelObject?.parent?.remove(this.labelObject);
  }
  focus() {}
  blur() {}
}
